/* this source file include definitions defined in 4 source files
 * phys_mm.c, virt_mm.c, and page_mm.c. I know its considered bad
 * practice to have one header for 3 sources, but I only did it
 * to organize the overall memory manager in parts and make it
 * easier to read and understand. mm.c is the main source file 
 */

#include "typedef.h"

#define		PAGE_SIZE		 4096
#define         PG_PRES                  0x00000001
#define         PG_READ                  0x0
#define         PG_WRITE                 0x00000002
#define         PG_USER                  0x00000004
#define         PG_SUPER                 0x0

// paging macros for accessing page flags
#define		PG_ALIGN(X)			(X & 0xfffff000)
#define         PG_FRAME(X)                     (X & 0xfffff000)
#define         PDE_OFFSET(X)                   (X >> 22)
#define         PTE_OFFSET(X)                   ((X & 0x003ff000) >> 12)
#define		PG_VALID(X)			(X & 0x00000001)
#define		PG_DIRTY(X)			(X & 0x00000040)
#define		PG_ACCESSED(X)			(X & 0x00000020)


// a page is essentially just 4 bytes. Use macros to get info about i

typedef u32 page_t;

typedef struct pte {
  page_t pages[1024];
} pte_t;

typedef struct pde {
  pte_t* tables[1024];
  u32 tables_phys[1024];
} pde_t;

/****************************************************************
// functions for mm.c
***************************************************************/

void init_mm();
pde_t* make_user_space(u32, u32);

/****************************************************************
// functions for page_mm.c
***************************************************************/

void init_paging();
u32 virt_to_phys(pde_t*, u32);
void switch_page_directory(pde_t*);

/****************************************************************
// functions for virt_mm.c
***************************************************************/

void init_virt_mm();

/****************************************************************
// functions for phys_mm.c
***************************************************************/
void init_phys_mm();
u32 get_frame();
void free_frame(u32);

